#!/usr/bin/env Rscript

## ####################
## Package Dependencies
## ####################

suppressMessages({
    library("foreach")
    library("doRNG")
    library("plyr")
}
                 )

## ##############
## Define Handoff
## ##############

BATON <- new.env()

## ################
## Env Dependencies
## ################

isDistMem <- as.integer(Sys.getenv("DISTMEM"))
nProcs <- as.integer(Sys.getenv("PROCS"))
nMC <- as.integer(Sys.getenv("MC"))
nThreads <- as.integer(Sys.getenv("THREADS"))
thisType <- Sys.getenv("TYPE")

## #########
## Set Paths
## #########

p2root <- "../../../"
p2estimates <- paste(p2root, "data/RDATA/estimates2/", sep = "")
p2output <-file.path(p2root, "data/CSV/mc", paste(thisType, "csv", sep = "."))
source(paste(p2root, "src/R/functions/simulator.R", sep = ""), local = BATON)
load(paste(p2estimates, "hou112.Rdata", sep = ""), BATON)

## #################
## Data Dependencies
## #################

dfCombosA <- data.frame(N = 500,
                        J = c(50, 100, 250, 500, 10e2, 15e2, 20e2, 25e2, 50e2),
                        group = "N"
                        )

dfCombosB <- data.frame(N = c(50, 100, 250, 500, 10e2, 2500, 5000, 75e2, 100e2),
                        J = 1000,
                        group = "J"
                        )


dfCombos <- rbind(dfCombosA,
                  dfCombosB
                  )


dfGrid <- ddply(dfCombos,
                c("N", "J", "group"),
                function(df) data.frame(MC = 1:nMC)
                )

dfGrid

BATON$dfGrid <- dfGrid


## ############################
## Shared or Distributed Memory
## ############################

if (isDistMem == 1) {
    ## cat("\nDIST MEM\n")
    suppressMessages({
        library("doMPI")
    }
                     )
    cl <- startMPIcluster()
    registerDoMPI(cl)
} else {
    ## cat("\nsingle node\n")
    suppressMessages({
        library("doMC")
    }
                     )
    registerDoMC(nProcs)
}
registerDoRNG()

## #########
## MC Trials
## #########

g <- 1

dfOut <- foreach(g = 1:nrow(dfGrid),
                 .combine = rbind,
                 .export = "BATON",
                 .errorhandling = "remove",
                 .multicombine = FALSE
                 )  %dopar% {
                     attach(BATON)
                     suppressMessages({
                         require("emIRT")
                     }
                                      )
                     thisN <- dfGrid$N[g]
                     thisJ <- dfGrid$J[g]
                     thisMC <- dfGrid$MC[g]
                     thisGroup <- dfGrid$group[g]
                     thisData <- generateData(out$xbar,
                                              out$betabar,
                                              thisN,
                                              thisJ,
                                              2
                                              )
                     starts <- getStarts(thisN, thisJ, 1)
                     priors <- makePriors(thisN, thisJ, 1)
                     ftimes <- system.time({
                         fout <- binIRT(thisData$rc2,
                                        starts,
                                        priors,
                                        .control = (list(thresh = ifelse(thisType == "fastestLOW", 1e-2, 1e-6),
                                                         threads = nThreads,
                                                         asEM = TRUE
                                                         )
                                                    )
                                        )
                     }
                                           )
                     print(fout)
                     print(ftimes)
                     thisDF <- data.frame(type = thisType,
                                          times = ftimes[3],
                                          fit = fout$fit$csr,
                                          N = thisN,
                                          J = thisJ,
                                          MC = thisMC,
                                          group = as.character(thisGroup)
                                          )
                     return(thisDF)
                 }

write.csv(dfOut, file = p2output)

head(dfOut)

## #####################
## Shut Down Dist Memory
## #####################
if (isDistMem == 1) {
    closeCluster(cl)
    mpi.quit()
}

################################################################################
